#include "login.h"
#include "StdSqlite.h"
#include "StdFile.h"
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#include<stdlib.h>
#include<dirent.h>

#define true 1
#define false 0
#define UserTableName "UserData"
#define FriendTableName "friends"
#define OnlineUser "OnlineUsers"



struct Client
{
    int sock;
    char name[20];
};
typedef struct Client C;

struct Friend
{
    char name[30];
};
typedef struct Friend F;

F *CreateFriend(const char *name)
{
    F*f = (F*)malloc(sizeof(F));
    if(f == NULL)
    {
        printf("createFriedn malloc error\n");
        return NULL;
    }
    strcpy(f->name,name);
    return f;
}

void FreeFriend(F *f)
{
    if(f != NULL)
    {
        free(f);
    }
}

int start(User *user1)
{
    SQL *s = InitSqlite("./User_Account_data/USER.db");
    printf("==========================================================\n");
    printf("1.注册  2.登录  3.删除账号  4.退出\n");
    int choice = 0;
    scanf("%d", &choice);
    while(getchar()!='\n');
    switch (choice)
    {
        case 1:
            Register(user1,s);

            break;
        case 2:
            int flag = Login(user1,s);
            while(flag == false)
            {
                flag = Login(user1,s);
            }
            break;
        case 3:
            DeleteAccount(s);
            start(user1);
            break;
        case 4:
            exit(0);
        default:
            printf("没有该选项\n");
            start(user1);
            break;
    }
    FreeSqlite(s);
}

int Register(User *user1,SQL *s)
{

    printf("==========================================================\n");
    printf("正在注册\n");
    User user2 = {0, 0, 0};
    printf("输入昵称:");
    scanf("%s", user2.Name);
    while (getchar() != '\n');

    printf("输入账号:");
    scanf("%s", user2.account);
    while (getchar() != '\n')
        ;
    printf("输入密码:");
    scanf("%s", user2.passwd);
    while (getchar() != '\n')
        ;
    char *UserName = NULL;
    UserName = GetTableData2(s, UserTableName, user2.account);
    if (UserName == NULL)
    {
        char *value[] = {user2.account, user2.passwd, user2.Name};
        InsertData(s, UserTableName, value, sizeof(value) / sizeof(value[0]));
        printf("==========================================================\n");
        printf("注册成功正在返回主界面\n");

        CreateFriendTable(user2.Name);
        CreateChatRecordTable(user2.Name);
        CreateOfflineTable(user2.Name);
        MakeFileFolder(user2.Name);
        //MakeGroupFolder(user2.Name);
        CreateGroupTable(user2.Name);
        start(user1);
    }
    else
    {
        printf("已经存在该账号!!\n");
        printf("请重新输入\n");
        start(user1);
    }
}

int Login(User *user1,SQL *s)
{
    printf("==========================================================\n");
    printf("正在登录\n");

    printf("输入账号\n");
    scanf("%s", user1->account);
    printf("输入密码\n");
    scanf("%s", user1->passwd);

    char *UserName = GetTableData(s, UserTableName, user1->account, user1->passwd);
    if (UserName == NULL)
    {
        printf("==========================================================\n");
        printf("\033[31m账号或密码错误,请重新输入\033[0m\n");
        return false;
    }
    else
    {
        printf("登录成功\n");
        printf("用户%s,欢迎回来\n", UserName);
        strcpy(user1->Name, UserName);
        return true;
    }
    return 0;
}

void DeleteAccount(SQL *s)
{
    char account5[30];
    char passwd5[30];
    printf("==========================================================\n");
    printf("正在删除\n");
    printf("输入账号\n");
    scanf("%s",account5);
    printf("输入密码\n");
    scanf("%s",passwd5);
    DeleteTableAccount(s,UserTableName,account5,passwd5);
}

void DisplayRegisterUser()
{
    SQL *s = InitSqlite("./User_Account_data/USER.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,UserTableName,&result,&row,&column);
    
    for(int i = 1;i <=row;i ++)
    {
        printf("昵称:%s,账号:%s",result[i*column+2],result[i*column]);
        printf("\n");
    }
    sqlite3_free_table(result);
    FreeSqlite(s);
}

void CreateFriendTable(char *FromName)
{
    SQL *s = InitSqlite("./Friend/Friend.db");
    char *tableName = (char *)malloc(strlen(FromName));
    strcpy(tableName,FromName);
    char *prolist[] = {"FriendName","text"};
    CreateTable(s,tableName,prolist,sizeof(prolist)/sizeof(prolist[0])/2);
    free(tableName);
    FreeSqlite(s);
}

int MatchFriend(char *FromName, char *Toname)
{
    SQL* s = InitSqlite("./Friend/Friend.db");
    char **result;
    int row,column;
    GetTableInfo(s,FromName,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        // printf("%s  %s\n",Toname,result[i]);
        if(strcmp(Toname,result[i]) == 0)
        return false;//存在则返回false
    }
    return true;//不存在则返回true
    FreeSqlite(s);
}

void InsertFriendData(char *FromName, char *ToName)
{
    SQL* s = InitSqlite("./Friend/Friend.db");

    // char* myself = malloc(strlen(FromName) + 3);  // 添加额外的空间用于引号和字符串终止符
    // //sprintf(myself, "'%s'", FromName);
    // strcpy(myself,FromName);

    // char* friend = malloc(strlen(ToName) + 3);
    // //sprintf(friend, "'%s'", ToName);
    // strcpy(friend,ToName);
    // //printf("%s  %s\n", myself, friend);

    // char* value1[] = {myself, friend};
    // char* value2[] = {friend, myself};

    // InsertData(s, FriendTableName, value1, sizeof(value1) / sizeof(value1[0]));
    char *myself = (char *)malloc(strlen(FromName)+3);
    strcpy(myself,FromName);
    char *friend = (char *)malloc(strlen(ToName)+3);
    strcpy(friend,ToName);

    char *value1[] = {friend};
    char *value2[] = {myself};

    int flag = MatchFriend(FromName,ToName);
    if(flag == true)
    {
        InsertData(s,myself,value1,sizeof(value1)/sizeof(value1[0]));
        InsertData(s,friend,value2,sizeof(value2)/sizeof(value2[0]));
        printf("恭喜,您跟[%s]成为好友\n",FromName);
    }
    else
    {
        printf("你们两个已经是好友了\n");
    } 
    // 释放动态分配的内存
    free(myself);
    free(friend);
    FreeSqlite(s);
}

void DisplayFriends(char *FromName)
{
    SQL *s = InitSqlite("./Friend/Friend.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,FromName,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        printf("好友%s\n",result[i]);
    }
    sqlite3_free_table(result);
    FreeSqlite(s);
}

DLlist *GetFriendsData(char *FromName)
{
    DLlist *list = (DLlist*)malloc(sizeof(DLlist));
    InitDLlist(list);
    SQL *s = InitSqlite("./Friend/Friend.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,FromName,&result,&row,&column);
    for(int i =1;i <= row;i++)
    {
        InsertTail(list,CreateFriend(result[i]));
    }
    
    sqlite3_free_table(result);
    FreeSqlite(s);
    return list;
}

void DisplayOnlineFriends(char *FromName)
{
    SQL* s1 = InitSqlite("./User_Account_data/USER.db");
    SQL* s2 = InitSqlite("./Friend/Friend.db");
    char **result1;
    char **result2;
    int row1;
    int row2;
    int column1;
    int column2;//好友
    GetTableInfo(s1, OnlineUser, &result1, &row1, &column1);
    GetTableInfo(s2, FromName, &result2, &row2, &column2);
    char **result3 = (char**)malloc(row1 * sizeof(char*)); // 为result3分配内存
    for (int i = 0; i < row1; i++) 
    {
        result3[i] = (char*)malloc(31* sizeof(char));
    }
    int k = 0;
    for (int i = 1; i <=row1; i++) 
    { // 修正遍历的方式
        for (int j = 1; j <= row2; j++) 
        { // 修正遍历的方式
            if (strcmp(result1[i], result2[j]) == 0) 
            { // 使用strcmp函数进行字符串比较
                strcpy(result3[k], result1[i]);
                k++;
            }
        }
    }
    if(k == 0)
    {
        printf("没有好友在线\n");
    }
    else
    {
        for (int i = 0; i < k; i++) 
        {
            printf("好友%s在线\n", result3[i]);
        }
    }
    // 释放result3数组的内存
    for (int i = 0; i < row1; i++) 
    {
        free(result3[i]);
    }
    free(result3);
    sqlite3_free_table(result1);
    sqlite3_free_table(result2);
    FreeSqlite(s1);
    FreeSqlite(s2);
}

void deleteFriends(char *fromName, char *toName)
{
    SQL *s = InitSqlite("./Friend/Friend.db");
    char where[100] = {0};
    sprintf(where,"FriendName = '%s'",toName);
    DeleteData(s,fromName,where);
    sprintf(where,"FriendName = '%s'",fromName);
    DeleteData(s,toName,where);
    FreeSqlite(s);
}

void CreateChatRecordTable(char *FromName)
{
    SQL *s = InitSqlite("./ChatRecord/Record.db");
    char *tableName = (char *)malloc(strlen(FromName));
    strcpy(tableName,FromName);
    char *prolist[] = {"FromName","text","content","text","ToName","text"};
    CreateTable(s,tableName,prolist,sizeof(prolist)/sizeof(prolist[0])/2);
    free(tableName);
    FreeSqlite(s);
}

void ChatRecordSaved(char *FromName,char* content,char *ToName)
{
    SQL *s = InitSqlite("./ChatRecord/Record.db");
    char *values[] = {FromName,content,ToName};
    InsertData(s,FromName,values,sizeof(values)/sizeof(values[0]));
    InsertData(s,ToName,values,sizeof(values)/sizeof(values[0]));
    FreeSqlite(s);
}

void DisplayCharRecord(char *fromName)
{
    SQL *s = InitSqlite("./ChatRecord/Record.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,fromName,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        printf("发的人:%s 内容:%s 收的人:%s\n",result[i*column],result[i*column+1],result[i*column+2]);
    }
    sqlite3_free_table(result);
    FreeSqlite(s);
}

// void SetFriendStat(char *FromName, char *ToName,int flag)
// {
//     char *stat = (char *)malloc(10);//online offline
//     SQL *s = InitSqlite("./Friend/Friend.db");
//     if(flag == 1)
//     {
//         char setValue[1024] = "stat = 'online'";
//         char where[1024];
//         sprintf(where,"name = '%s'",ToName);
//         strcpy(stat,"online");
//         UpdateData(s,FromName,setValue,where);
//     }
//     else 
//     {
//         char setValue[1024] = "stat = 'offline'";
//         char where[1024];
//         sprintf(where,"name = '%s'",ToName);
//         strcpy(stat,"online");
//         UpdateData(s,FromName,setValue,where);
//         strcpy(stat,"offline");
//     }

// }

int IsUserExit(char *name)
{
    SQL*s = InitSqlite("./User_Account_data/USER.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,UserTableName,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        //printf("%s\n",result[i*column+2]);
        if(strcmp(name,result[i*column+2]) == 0)
        {
            return true;
        }
    }
    return false;
    sqlite3_free_table(result);
    FreeSqlite(s);
}

void InsertOnlineUser(char *FromName)
{
    SQL*s = InitSqlite("./User_Account_data/USER.db");
    char *myself = (char*)malloc(strlen(FromName)+3);
    strcpy(myself,FromName);
    char* value[] = {myself};
    InsertData(s,OnlineUser,value,sizeof(value)/sizeof(value[0]));

    free(myself);
    FreeSqlite(s);
}

void DisplayOnlineUser()
{
    SQL*s = InitSqlite("./User_Account_data/USER.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,OnlineUser,&result,&row,&column);
    
    for(int i = 1;i <=row;i ++)
    {
        printf("昵称:%s在线\n",result[i]);
    }
    sqlite3_free_table(result);
    FreeSqlite(s);
}

void DeleteOnlineUser(char *FromName)
{
    SQL*s = InitSqlite("./User_Account_data/USER.db");
    DeleteOnlineData(s,OnlineUser,FromName);
    FreeSqlite(s);
}

void MakeGroupFolder(char *name)
{
    MakeDir2(name);
}

void CreateGroupTable(char *name)
{
    SQL *s = InitSqlite("./QQgroup/user.db");
    char *prolist[] = {"加入的群","text"};
    if(CheckTableExists(s,name) == 0)
    {
        CreateTable(s,name,prolist,sizeof(prolist)/sizeof(prolist[0])/2);
    }
    FreeSqlite(s);
}

void CreateQQGroup(char *fromName, char *name1)
{
    char name[100] = {0};
    strcpy(name,name1);
    while(getchar()!='\n');
    SQL *s1 = InitSqlite("./QQgroup/Group.db");
    SQL *s2 = InitSqlite("./QQgroup/GroupChat.db");
    SQL *s3 = InitSqlite("./QQgroup/user.db");
    char *prolist1[] = {"群人员","text"};
    char *prolist2[] = {"FromName","text","content","text"};
    char *prolist3[] = {"加入的群","text"};

    if(CheckTableExists(s1,name) == 0)
    {
        CreateTable(s1,name,prolist1,sizeof(prolist1)/sizeof(prolist1[0])/2);
    }
    if(CheckTableExists(s2,name) == 0)
    {
        CreateTable(s2,name,prolist2,sizeof(prolist2)/sizeof(prolist2[0])/2);
    }
    if(CheckTableExists(s3,fromName) == 0)
    {
        CreateTable(s3,fromName,prolist3,sizeof(prolist3)/sizeof(prolist3[0])/2);
    }
    FreeSqlite(s1);
    FreeSqlite(s2);
    FreeSqlite(s3);
}

void PullGroup2(char *fromName,char *groupName)
{
    SQL*s1 = InitSqlite("./QQgroup/Group.db");
    SQL*s2 = InitSqlite("./QQgroup/user.db");
    char *fromName1 = (char *)malloc(strlen(fromName)+2);
    char *groupName1 = (char *)malloc(strlen(groupName)+2);
    strcpy(fromName1,fromName);
    strcpy(groupName1,groupName);
    //printf("%s  %s\n",fromName1,groupName1);
    char *value1[] = {fromName1};
    char *value3[] = {groupName1};
    if(MatchQQGroup(fromName1,groupName1) == true)
    {
        InsertData(s1,groupName1,value1,sizeof(value1)/sizeof(value1[0]));
    }
    if(MatchQQuser(fromName1,groupName1) == true)
    {
        InsertData(s2,fromName1,value3,sizeof(value3)/sizeof(value3[0]));
    }
    free(fromName1);
    free(groupName1);
    FreeSqlite(s1);
    FreeSqlite(s2);
}

void PullGroup(char *fromName, char *ToName,char *groupName)
{
    SQL*s1 = InitSqlite("./QQgroup/Group.db");
    SQL*s2 = InitSqlite("./QQgroup/user.db");

    char *fromName1 = (char *)malloc(strlen(fromName)+2);
    char *toName1 = (char *)malloc(strlen(ToName)+2);
    char *groupName1 = (char *)malloc(strlen(groupName)+2);

    strcpy(fromName1,fromName);
    strcpy(toName1,ToName);
    strcpy(groupName1,groupName);
    //printf("%s  %s\n",fromName1,groupName1);
    char *value1[] = {fromName1};
    char *value2[] = {toName1};
    char *value3[] = {groupName1};

    if(MatchQQGroup(fromName1,groupName1) == true)
    {
        InsertData(s1,groupName1,value1,sizeof(value1)/sizeof(value1[0]));
    }
    if(MatchQQGroup(toName1,groupName1) == true)
    {
        InsertData(s1,groupName1,value2,sizeof(value2)/sizeof(value2[0]));
    }
    
    if(MatchQQuser(fromName1,groupName1) == true)
    {
        InsertData(s2,fromName1,value3,sizeof(value3)/sizeof(value3[0]));
    }
    if(MatchQQuser(toName1,groupName1) == true)
    {
        InsertData(s2,toName1,value3,sizeof(value3)/sizeof(value3[0]));
    }
    free(fromName1);
    free(toName1);
    free(groupName1);
    FreeSqlite(s1);
    FreeSqlite(s2);
}

int CheckQQGroupExit(char *TableName)
{
    SQL *s = InitSqlite("./QQgroup/Group.db");
    if(CheckTableExists(s,TableName) == 1)
    {
        return true;//表格存在
    }
    else 
    {
        return false;//表格不存在
    }
    FreeSqlite(s);
    return 0;
}

int MatchQQGroup(char *Name, char *groupName)
{
    SQL *s = InitSqlite("./QQgroup/Group.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,groupName,&result,&row,&column);
    for(int i = 1;i <= row;i++)
    {
        if(strcmp(Name,result[i]) == 0)
        {
            return false;//群存在则返回false
        }
    }
    return true;//不存在则返回true
    sqlite3_free_table(result);
    FreeSqlite(s);
}

int MatchQQuser(char *name, char *groupName)
{

    SQL *s = InitSqlite("./QQgroup/user.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,name,&result,&row,&column);
    for(int i = 1;i <= row;i++)
    {
        if(strcmp(groupName,result[i]) == 0)
        {
            return false;//存在返回false
        }
    }
    return true;//不存在返回true
    sqlite3_free_table(result);
    FreeSqlite(s);
}

DLlist *GetGroupMembers(char *groupName)
{
    DLlist *list = (DLlist*)malloc(sizeof(DLlist));
    InitDLlist(list);
    SQL *s = InitSqlite("./QQgroup/Group.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,groupName,&result,&row,&column);
    for(int i =1;i <= row;i++)
    {
        InsertTail(list,CreateFriend(result[i]));
    }
    // struct Node *tra = list->head;
    // while(tra!= NULL)
    // {
    //     F *f = (F*)tra->data;
    //     printf("成员 = %s\n",f->name);
    //     tra = tra->next;
    // }
    sqlite3_free_table(result);
    FreeSqlite(s);
    return list;
}

DLlist *FindGroupIntersection(DLlist *list1, DLlist *list2)
{
    struct Node* tra1 = list1->head;
    struct Node* tra2 = list2->head;
    DLlist *list3 = (DLlist*)malloc(sizeof(DLlist));
    if(list3 == NULL)
    {
        printf("FindIntersection malloc error\n");
    }
    InitDLlist(list3);
  
    while(tra1 !=NULL)
    {
        C *c = (C*)tra1->data;
        tra2 = list2->head;//warning!!!!!每次都需要重置tra2!!!!
        while(tra2 !=NULL)
        {
            F *f = (F*)tra2->data;
            if(strcmp(c->name,f->name) == 0)//字符串匹配
            {
                struct Node* tra3 = list3->head;
                int flag = 0;
            
                while(tra3 != NULL)
                {
                    if(tra3->data == tra1->data)
                    {
                        flag = 1;
                    }
                    tra3 = tra3->next;
                }
                if(flag == 0)
                {
                    InsertTail(list3,tra1->data);
                }
            }
            tra2 = tra2->next;
        }
        tra1 = tra1->next;
    }
    return list3;
}

void insertGroupChat(char *fromName, char *content, char *groupName)
{
    //printf("%s  %s  %s\n",fromName,content,groupName);
    SQL *s = InitSqlite("./QQgroup/GroupChat.db");
    char *value[] = {fromName,content};
    InsertData(s,groupName,value,sizeof(value)/sizeof(value[0]));

    FreeSqlite(s);
}

int IsOnline(char*name)
{
    //printf("%s\n",name);
    SQL*s = InitSqlite("./User_Account_data/USER.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,OnlineUser,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        
        //printf("%s\n",result[i]);
        if(strcmp(name,result[i]) == 0)
        {
            
            return true;//true为在线
        }
    }
    return false;//false为离线
    sqlite3_free_table(result);
    FreeSqlite(s);
}

void CreateOfflineTable(char *FromName)
{
    SQL *s = InitSqlite("./OfflineLibrary/offline.db");
    char *tableName = (char *)malloc(strlen(FromName));
    strcpy(tableName,FromName);
    char *prolist[] = {"发消息的人","text","内容","text"};
    CreateTable(s,tableName,prolist,sizeof(prolist)/sizeof(prolist[0])/2);
    free(tableName);
    FreeSqlite(s);
}

void insertOfflineChat(char *FromName, char *content, char *ToName)
{
    SQL *s = InitSqlite("./OfflineLibrary/offline.db");
    char *value[] = {FromName,content};
    InsertData(s,ToName,value,sizeof(value)/sizeof(value[0]));
    FreeSqlite(s);
}

void DisplayOfflineChat(char *name)
{
    SQL *s = InitSqlite("./OfflineLibrary/offline.db");
    char **result;
    int row;
    int column;
    GetTableInfo(s,name,&result,&row,&column);
    for(int i = 1; i <= row;i++)
    {
        printf("%s发送的内容为%s\n",result[i*column],result[i*column+1]);
    }
    sqlite3_free_table(result);
    FreeSqlite(s);
}

void deleteOfflineChat(char *name)
{
    SQL *s = InitSqlite("./OfflineLibrary/offline.db");
    ClearDataTable(s,name);
    FreeSqlite(s);
}



void MakeFileFolder(char *name)
{
    MakeDir1(name);
}

int IfFolderExit(char *name,char *FromName)
{

    char account[100]= {0};
    strcpy(account,name);

    char temp[200] ="./";
    strcat(temp,"FileLibrary");
    strcat(temp,"/");
    strcat(temp,FromName);

    const char* folderPath = temp;
    const char* fileName = account;

    // 打开文件夹
    DIR* folder = opendir(folderPath);
    if (folder == NULL) 
    {
        printf("文件夹不存在\n");
        return 0;
    }

    // 遍历文件夹中的文件
    struct dirent* entry;
    int fileExists = 0;
    while ((entry = readdir(folder)) != NULL) 
    {
        if (strcmp(entry->d_name,fileName) == 0)
         {
            // 找到指定的文件
            fileExists = 1;
            break;
        }
    }

    // 关闭文件夹
    closedir(folder);

    if (fileExists == 1) 
    {
        return true;
    } 
    else 
    {
        return false;
    }
    
}


int IfFolderExit2(char *name,char *FromName)
{

    char account[100]= {0};
    strcpy(account,name);

    char temp[200] ="./";
    strcat(temp,"QQgroup");
    strcat(temp,"/");
    strcat(temp,"GroupFile");
    strcat(temp,"/");
    strcat(temp,FromName);

    const char* folderPath = temp;
    const char* fileName = account;
    //printf("tmo = %s\n",temp);
    
    // 打开文件夹
    DIR* folder = opendir(folderPath);
    if (folder == NULL) 
    {
        printf("文件夹不存在\n");
        return 0;
    }

    // 遍历文件夹中的文件
    struct dirent* entry;
    int fileExists = 0;

    while ((entry = readdir(folder)) != NULL) 
    {
        if (strcmp(entry->d_name, fileName) == 0)
         {
            // 找到指定的文件
            fileExists = 1;
            break;
        }
    }

    // 关闭文件夹
    closedir(folder);

    if (fileExists == 1) 
    {
        return true;
    } 
    else 
    {
        return false;
    }
    
}